package model

import (
	"context"
	sq "github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"gorm.io/gorm"
	"strings"
	"xialou_platform/app/requestx"
)

var _ AgentUserModel = (*customAgentUserModel)(nil)

type (
	// AgentUserModel is an interface to be customized, add more methods here,
	// and implement the added methods in customAgentUserModel.
	AgentUserModel interface {
		agentUserModel
		FindListCount(ctx context.Context, agentId, status int64) int64
		FindList(ctx context.Context, page *requestx.ListReq, agentId, status int64) ([]*AgentUser, error)

		FindBindUserCount(ctx context.Context, agentId int64) int64
		FindActiveBindCountByCatdIDs(ctx context.Context, ids string) int64
	}

	customAgentUserModel struct {
		*defaultAgentUserModel
	}
)

// NewAgentUserModel returns a model for the database table.
func NewAgentUserModel(conn sqlx.SqlConn, c cache.CacheConf) AgentUserModel {
	return &customAgentUserModel{
		defaultAgentUserModel: newAgentUserModel(conn, c),
	}
}

func (m *defaultAgentUserModel) FindListCount(ctx context.Context, agentId, status int64) int64 {
	selectBuilder := sq.Select("count(1)").From(m.table)
	if agentId > 0 {
		selectBuilder = selectBuilder.Where(sq.Eq{"agent_id": agentId})
	}
	if status > -1 {
		selectBuilder = selectBuilder.Where(sq.Eq{"status": status})
	}

	query, args, err := selectBuilder.PlaceholderFormat(sq.Dollar).ToSql()
	if err != nil {
		return 0
	}
	var count int64
	err = m.QueryRowNoCacheCtx(ctx, &count, query, args...)
	if err != nil {
		return 0
	}
	return count

}

func (m *defaultAgentUserModel) FindList(ctx context.Context, page *requestx.ListReq, agentId, status int64) ([]*AgentUser, error) {
	selectBuilder := sq.Select(agentUserRows).From(m.table).Limit(page.Limit()).Offset(page.Offset())
	if agentId > 0 {
		selectBuilder = selectBuilder.Where(sq.Eq{"agent_id": agentId})
	}
	if status > -1 {
		selectBuilder = selectBuilder.Where(sq.Eq{"status": status})
	}
	query, args, err := selectBuilder.OrderBy("create_time desc").PlaceholderFormat(sq.Dollar).ToSql()
	if err != nil {
		return nil, err
	}
	var resp []*AgentUser
	err = m.QueryRowsNoCacheCtx(ctx, &resp, query, args...)
	return resp, err
}

func (m *defaultAgentUserModel) FindBindUserCount(ctx context.Context, agentId int64) int64 {
	selectBuilder := sq.Select("count(1)").From(m.table).
		LeftJoin("agent on agent.id = agent_Id").
		Where(sq.Eq{"agent.status": 2}).Where(sq.Or{sq.Eq{"agent_id": agentId}, sq.Eq{"parent_uid": agentId}, sq.Eq{"top_uid": agentId}})

	query, args, err := selectBuilder.PlaceholderFormat(sq.Dollar).ToSql()
	if err != nil {
		return 0
	}
	var count int64
	err = m.QueryRowNoCacheCtx(ctx, &count, query, args...)
	if err != nil {
		return 0
	}
	return count
}

func (m *defaultAgentUserModel) FindActiveBindCountByCatdIDs(ctx context.Context, ids string) int64 {

	var count int64
	idsSlice := strings.Split(ids, ",") // 将逗号分隔的字符串转换为切片

	// 如果 idsSlice 为空，直接返回 0
	if len(idsSlice) == 0 {
		return 0
	}

	// 构建占位符字符串，例如 "$1, $2, $3" 根据 idsSlice 的长度
	placeholders := make([]interface{}, len(idsSlice))
	for i, id := range idsSlice {
		placeholders[i] = id
	}

	// 使用 squirrel 构建查询
	selectBuilder := sq.Select("count(1)").From("agent_user").
		Where(sq.Eq{"source_type": 1}).
		Where(sq.Eq{"source_id": placeholders})

	query, args, err := selectBuilder.PlaceholderFormat(sq.Dollar).ToSql()
	if err != nil {
		return 0
	}

	err = m.QueryRowNoCacheCtx(ctx, &count, query, args...)
	if err != nil {
		return 0
	}

	return count
}

// 获取代理商下的用户列表
func AgentUserFindList(db *gorm.DB, agentID, status, sourceType int64, page, size uint64) ([]AgentUser, int64, error) {
	var users []AgentUser
	var total int64
	sqlBuild := db.Model(&AgentUser{})
	if status != -1 {
		sqlBuild = sqlBuild.Where("status = ?", status)
	}
	if agentID != 0 {
		sqlBuild = sqlBuild.Where("agent_id = ?", agentID)
	}
	if sourceType != -1 {
		sqlBuild = sqlBuild.Where("source_type = ?", sourceType)
	}
	sqlBuild.Count(&total)
	err := sqlBuild.Debug().Limit(int(size)).Offset(int((page - 1) * size)).Order("create_time desc").Find(&users).Error
	if err != nil {
		return nil, total, err
	}
	return users, total, nil
}
